import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _inherits from "@babel/runtime/helpers/esm/inherits";
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
import _startsWith from "lodash/startsWith";
import _isObject from "lodash/isObject";
import _forEach from "lodash/forEach";

/* eslint-disable no-underscore-dangle, no-param-reassign */
import React from 'react';
import EventEmitter from 'event-emitter';
import { getActiveTabKey } from "../../utils/menuTab";
var emitter = new EventEmitter(); // const CLEAR_MAP = {};

var CACHE_MAP = {};
var WILL_CACHE_PRE_MAP = {};

function getWillCacheCount(cachePreKey) {
  var _WILL_CACHE_PRE_MAP$c = WILL_CACHE_PRE_MAP[cachePreKey];
  _WILL_CACHE_PRE_MAP$c = _WILL_CACHE_PRE_MAP$c === void 0 ? {
    willCacheCount: 0
  } : _WILL_CACHE_PRE_MAP$c;
  var willCacheCount = _WILL_CACHE_PRE_MAP$c.willCacheCount;
  return willCacheCount;
} // 当 缓存组件 didMount 时 cachePreKey 计数 +1


emitter.on('willCache', function (cachePreKey) {
  if (WILL_CACHE_PRE_MAP[cachePreKey]) {
    WILL_CACHE_PRE_MAP[cachePreKey].willCacheCount = Math.max(1, WILL_CACHE_PRE_MAP[cachePreKey].willCacheCount);
  } else {
    WILL_CACHE_PRE_MAP[cachePreKey] = {
      willCacheCount: 1
    };
  }
}); // 当缓存组件 willUnmount 时 cachePreKey 计数 -1 并将 cacheKey 对应的缓存写进缓存

emitter.on('save', function (cacheKey, data, cachePreKey) {
  WILL_CACHE_PRE_MAP[cachePreKey].willCacheCount = Math.max(0, getWillCacheCount(cachePreKey) - 1);
  setCache(cacheKey, data);
}); // 如果 Tab 没有关闭, 会添加一个 清除方法 在 组件触发缓存后 立即清空缓存 直至 全部清除完毕 后清除 清除方法

emitter.on('clean', function (cachePreKey) {
  if (getWillCacheCount(cachePreKey) > 0) {
    var cleanFunc = function cleanFunc(cacheKey, _, componentCachePreKey) {
      if (cachePreKey === componentCachePreKey) {
        delete CACHE_MAP[cacheKey];

        if (getWillCacheCount(cachePreKey) === 0) {
          emitter.off('save', cleanFunc);
        }
      }
    };

    emitter.on('save', cleanFunc);
  } else {
    cleanCacheData(cachePreKey);
  }
});
/**
 * 通过 cacheKey 删除缓存
 * @param {String} cacheKey - 缓存的key
 */

export function deleteCache(cacheKey) {
  if (cacheKey) {
    delete CACHE_MAP[cacheKey];
  }
}

function setCache(key, data) {
  CACHE_MAP[key] = data;
}

function getCache(key) {
  if (key) {
    return CACHE_MAP[key];
  }
}
/**
 * @param {!String} cachePreKey - 删除对应 缓存头的 key
 */


function cleanCacheData(cachePreKey) {
  var removeCacheKeys = []; // CLEAR_MAP[cachePreKey] = true;

  _forEach(CACHE_MAP, function (_, cacheKey) {
    if (_startsWith(cacheKey, cachePreKey)) {
      // CLEAR_MAP[cacheKey] = true;
      removeCacheKeys.push(cacheKey);
    }
  });

  _forEach(removeCacheKeys, function (cacheKey) {
    delete CACHE_MAP[cacheKey];
  });
}

export function cleanCache(cachePreKey) {
  emitter.emit('clean', cachePreKey); // cleanCacheData(cachePreKey);
}
export default function cacheComponent() {
  var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
      cacheKey = _ref.cacheKey,
      _ref$cachePreKey = _ref.cachePreKey,
      cachePreKey = _ref$cachePreKey === void 0 ? getActiveTabKey() : _ref$cachePreKey;

  return function (Component) {
    return /*#__PURE__*/function (_React$Component) {
      _inherits(CacheComponent, _React$Component);

      var _super = _createSuper(CacheComponent);

      function CacheComponent() {
        var _this;

        _classCallCheck(this, CacheComponent);

        for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
          args[_key] = arguments[_key];
        }

        _this = _super.call.apply(_super, [this].concat(args));

        _this.setComponent = function (component) {
          _this.pageComponent = component;
        };

        return _this;
      }

      _createClass(CacheComponent, [{
        key: "loadCache",
        value: function loadCache(component, callback) {
          if (cacheKey) {
            var form = component.props.form;
            var cache = getCache(cacheKey);

            if (form && cache && cache.form) {
              if (_isObject(cache.form)) {// Object.keys(cache.form).forEach((item) => form.registerField(item));
              }

              form.setFieldsValue(cache.form);
            }

            if (cache && cache.state) {
              component.setState(cache.state, function () {
                if (callback) callback();
              });
            } else if (callback) {
              callback();
            }
          }
        }
      }, {
        key: "componentWillUnmount",
        value: function componentWillUnmount() {
          // if(CLEAR_MAP[cacheKey]){
          //   delete CLEAR_MAP[cacheKey];
          // }else{
          if (cacheKey && this.pageComponent) {
            var form = this.pageComponent.props.form;
            var cache = {};

            if (form) {
              var getFieldsValue = form.getFieldsValue;
              cache.form = getFieldsValue();
            }

            if (this.pageComponent.state) {
              cache.state = this.pageComponent.state;
            } // setCache(cacheKey,cache);


            emitter.emit('save', cacheKey, cache, cachePreKey);
          } // }

        }
      }, {
        key: "fakeComponentDidMount",
        value: function fakeComponentDidMount(Comp) {
          if (Comp._isFakeComponentDidMount !== true) {
            var componentDidMount = Comp.prototype.componentDidMount;
            var loadCache = this.loadCache;

            Comp.prototype.componentDidMount = function newComponentDidMount() {
              var _this2 = this;

              emitter.emit('willCache', cachePreKey);
              loadCache(this, function () {
                if (typeof componentDidMount === 'function') {
                  componentDidMount.call(_this2);
                }
              });
            };

            Comp._isFakeComponentDidMount = true;
          }
        }
      }, {
        key: "render",
        value: function render() {
          this.fakeComponentDidMount(Component);
          return /*#__PURE__*/React.createElement(Component, Object.assign({
            ref: this.setComponent
          }, this.props));
        }
      }]);

      return CacheComponent;
    }(React.Component);
  };
}